#pragma once
// 业务分发器，对服务器受到的数据进行解析，Json 处理等，分发给对应的业务模块

#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <websocketpp/frame.hpp>
typedef websocketpp::server<websocketpp::config::asio> server;
typedef websocketpp::connection_hdl con_hdl;
typedef server::message_ptr msg_ptr;

#include <iostream>
#include <thread>
#include <json/json.h>

#include "send_to_qml.hpp"
#include "UserManagement.hpp"
#include "FileManagement.hpp"
#include "MsgRouting.hpp"
#include "GroupMgt.hpp"

class op_distributor
{
private:
    FileMgt file_mgt_;
    MsgRouting msg_routing_;
    GroupMgt group_mgt_;

public:
    op_distributor(/* args */);
    ~op_distributor();
    // 分发数据
    void processing_data(server *s, con_hdl hdl, msg_ptr msg,std::thread* thread_sever);
    void processing_text(server *s, con_hdl hdl, msg_ptr msg,std::thread* thread_sever);
    void processing_binary(server *s, con_hdl hdl, msg_ptr msg);

    // 各个业务模块
    void user_register(std::string nickname, std::string password, con_hdl hdl, server *s,std::thread* thread_sever)
    {
        //std::cout << "op_dis.user_register thread   " << std::this_thread::get_id() << std::endl;
        UserMgt::create_user(nickname, password, hdl, s, thread_sever);
    }
    void user_login(std::string nickname, std::string password, con_hdl hdl)
    {
        UserMgt::user_login(nickname, password, hdl);
    }
    void flush_user_info(int user_id, con_hdl hdl, server *s)
    {
        std::cout << "flush_user_info " << user_id << std::endl << std::endl;
        UserMgt::flush_user_info(user_id,hdl,s);
    }
    void flush_group_info(int group_id, con_hdl hdl, server *s)
    {
        std::cout << "flush_group_info " << group_id << std::endl << std::endl;
        group_mgt_.flush_group_info(group_id,hdl,s);
    }
    void add_friend(std::string my, std::string your, std::string verification,server *s, con_hdl hdl)
    {
        msg_routing_.add_friend(my, your, verification,s,hdl);
    }
    void user_logout(int user_id)
    {
        UserMgt::user_logout(user_id);
    }
    void get_msg(int user_id,std::string name)
    {
        //std::cout << "业务分发: get_msg" << user_id << name << std::endl;
        msg_routing_.get_msg(user_id,name);
    }
    void add_user_relationship(std::string nickname_1,std::string nickname_2,std::string rela)
    {
        UserMgt::add_user_rela(nickname_1,nickname_2,rela);
    }
    void flush_friend_list(int id)
    {
        UserMgt::flush_qml_friend_list(id);
    }
    void flush_group_list(int id)
    {
        //UserMgt::flush_qml_friend_list(id);
        group_mgt_.flush_qml_group_list(id);
    }
    void set_user_info(int id, std::string* info)
    {
        UserMgt::set_user_info(id, info);
    }
    void send_text_msg(std::string send_name,std::string recv_name,std::string content)
    {
        msg_routing_.send_text_msg(send_name,recv_name,content);
    }
    void send_emoji_msg(std::string send_name,std::string recv_name,std::string content)
    {
        msg_routing_.send_emoji_msg(send_name,recv_name,content);
    }
    void send_file_msg(std::string send_name,std::string recv_name,std::string file_name,std::string file_size)
    {
        msg_routing_.send_file_msg(send_name,recv_name,file_name,file_size);
    }
    void upload_user_avatar(int user_id, int image_size, con_hdl hdl)
    {
        std::cout << "客户端请求上传头像, id:  " << user_id << image_size << std::endl << std::endl;
        UserMgt::upload_user_avatar(user_id, image_size, hdl); // 客户端请求上传头像
    }
    void upload_file(std::string file_name, int file_size, con_hdl hdl)
    {
        file_mgt_.upload_file_before(file_name,file_size,hdl);
    }
    void download_file(std::string file_name, server *s, con_hdl hdl)
    {
        file_mgt_.download_file(file_name, s, hdl);
    }
    void create_group(std::string group_name, std::string user_names,con_hdl hdl)
    {
        group_mgt_.create_group(group_name, user_names,hdl);
    }
    // 发送群消息
    void send_group_msg(std::string group_name, std::string user_name,std::string kind,std::string c1,std::string c2)
    {
        msg_routing_.send_group_msg(group_name, user_name, kind, c1, c2);
    }

    void flush_user_info_with_name(std::string user_name,con_hdl hdl, server *s)
    {
        UserMgt::flush_user_info_with_name(user_name,hdl,s);
    }
    
};

void op_distributor::processing_data(server *s, con_hdl hdl, msg_ptr msg, std::thread* thread_sever)
{
    int opcode = msg->get_opcode();
    if(opcode == websocketpp::frame::opcode::TEXT)
        processing_text(s,hdl,msg,thread_sever);
    else if(opcode == websocketpp::frame::opcode::BINARY)
        processing_binary(s,hdl,msg);
    else if(opcode == websocketpp::frame::opcode::CONTINUATION)
        std::cout << "分片数据\n" << msg->get_raw_payload() << std::endl;
    else
        std::cout << "未知的 get_opcode " << std::endl;


    // con_hdl h = hdl;
    // std::cout << "op_distributor::processing_data" << std::endl;
    
    // std::cout << "msg: "  << msg << std::endl;
    //在新线程中处理后续业务
    // std::thread new_thread([=]() {
        // 这里会崩溃，不能在主线程之外的其它线程里使用 websocketpp::server<websocketpp::config::asio>
        // std::cout << "新线程：" << std::endl;
        // s->send(hdl, "我是服务器", websocketpp::frame::opcode::TEXT);

        // con_hdl& h = hdl; // 将 "con_hdl &" 类型的引用绑定到 "const con_hdl" 类型的初始值设定项时，限定符被丢弃
        // lambd [=] 值捕获后，con_hdl& hdl 变成了 const con_hdl&
        // 所以要使用 引用捕获 [&]
        // std::cout << "msg: " << msg << std::endl;
        // 注意 lambda 函数的参数捕获问题，这里 msg 如果使用 &msg 引用捕获，则捕获前后 msg 的值会不一样！

    // });
    // new_thread.detach(); // 在新线程上运行，分离线程以避免资源泄漏
}

void op_distributor::processing_text(server *s, con_hdl hdl, msg_ptr msg,std::thread* thread_sever)
{
    // std::cout << "op_dis.processing_text thread   " << std::this_thread::get_id() << std::endl;

    // Json
    // 解析 JSON 字符串
    Json::Value root;
    Json::Reader reader;
    if (!reader.parse(msg->get_payload(), root)) 
        std::cerr << "op_distributor::processing_text JSON解析错误!" << reader.getFormattedErrorMessages() << std::endl;
    

    std::string op = root["op"].asString();
        
    if (op == "register") // 用户注册
    {
        user_register(root["nickname"].asString(), root["password"].asString(), hdl, s, thread_sever);
    }
    else if (op == "login") // 用户登录
    {
        user_login(root["nickname"].asString(), root["password"].asString(), hdl);
    }
    else if (op == "upload_user_avatar") // 用户上传头像
    {
        upload_user_avatar(root["user_id"].asInt(), root["image_size"].asInt(), hdl);
    }
    else if (op == "flush_user_info") // 刷新用户信息
    {
        flush_user_info(root["user_id"].asInt(),hdl,s);
    }
    else if (op == "flush_group_info") // 刷新群组信息
    {
        flush_group_info(root["group_id"].asInt(),hdl,s);
    }
    else if(op == "add_friend") // 好友申请
    {
        // std::cout << "add_friend回应客户端" << std::endl;
        add_friend(root["my_nickname"].asString(),
        root["your_nickname"].asString(),root["verification"].asString(),s,hdl);
    }
    else if(op == "add_user_relationship") // 添加一条 user_relationship
    {
        //std::cout << "1" << std::endl;
        add_user_relationship(root["nickname_1"].asString(),root["nickname_2"].asString(),root["rela"].asString());
    }
    else if(op == "logout") // 用户登出
    {
        user_logout(root["user_id"].asInt());
    }
    else if(op == "get_msg")
    {
        get_msg(root["user_id"].asInt(), root["kind"].asString()); // 把数据库中 未递达的消息发送给对应的用户
    }
    else if(op == "flush_friend_list")
    {
        flush_friend_list(root["user_id"].asInt());
    }
    else if(op == "flush_group_list")
    {
        flush_group_list(root["user_id"].asInt());
    }
    else if(op == "set_user_info")
    {
        std::string info[4];
        info[0] = root["nickname"].asString();
        info[1] = root["gender"].asString();
        info[2] = root["tele"].asString();
        info[3] = root["signature"].asString();
        set_user_info(root["id"].asInt(),info);
    }
    else if(op == "send_text_msg")
    {
        send_text_msg(root["send_name"].asString(),root["recv_name"].asString(),root["content"].asString());
    }
    else if(op == "send_emoji_msg")
    {
        send_emoji_msg(root["send_name"].asString(),root["recv_name"].asString(),root["content"].asString());
    }
    else if(op == "send_file_msg")
    {
        send_file_msg(root["send_name"].asString(),root["recv_name"].asString(),root["file_name"].asString(),root["file_size"].asString());
    }
    else if(op == "upload_file")
    {
        upload_file(root["file_name"].asString(),root["file_size"].asInt(), hdl);
    }
    else if(op == "download_file")
    {
        download_file(root["file_name"].asString(), s, hdl);
    }
    else if(op == "create_group")
    {
        create_group(root["group_name"].asString(), root["user_names"].asString(),hdl);
    }
    else if(op == "send_group_msg")
    {
        send_group_msg(root["group_name"].asString(), root["user_name"].asString(),
        root["kind"].asString(), root["c1"].asString(),root["c2"].asString());
    }
    else if(op == "flush_user_info_with_name")
    {
        flush_user_info_with_name(root["user_name"].asString(),hdl,s);
    }
    
        
    
}

void op_distributor::processing_binary(server *s, con_hdl hdl, msg_ptr msg)
{
    file_mgt_.processing_binary(s, hdl, msg); // 让文件管理模块去处理二进制数据
}

op_distributor::op_distributor(/* args */)
{
}

op_distributor::~op_distributor()
{
}


